package cz.hackathon.core;

import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import cz.hackathon.rateit.model.Action;
import cz.hackathon.rateit.model.Category;
import cz.hackathon.rateit.model.Item;
import cz.hackathon.rateit.model.Location;
import cz.hackathon.rateit.model.Rating;

public class XmlParser {

	private Document document;

	Action parse(InputStream is) throws Exception {
		DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
		document = builder.parse(is);
		return createAction();
	}

	private Action createAction() throws Exception {
		Action action = new Action();
		NodeList list = document.getElementsByTagName("action");
		NodeList actionChildren = list.item(0).getChildNodes();

		for (int i = 0; i < actionChildren.getLength(); i++) {
			Node n = actionChildren.item(i);
			if (n.getNodeType() == Node.ELEMENT_NODE) {
				if (n.getNodeName().equals("description")) {
					action.setDescription(n.getTextContent());
				}
				if (n.getNodeName().equals("date")) {
					SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
					action.setDate(format.parse(n.getTextContent()));
				}
				if (n.getNodeName().equals("name")) {
					action.setName(n.getTextContent());
				}
				if (n.getNodeName().equals("items")) {
					action.setItems(parseItems(n.getChildNodes()));
				}
				if (n.getNodeName().equals("location")) {
					action.setLocation(parseLocation(n.getChildNodes()));
				}
			}
		}
		return action;
	}

	private Location parseLocation(NodeList nodeList) {
		Location location = new Location();
		for (int i = 0; i < nodeList.getLength(); i++) {
			Node n = nodeList.item(i);
			if (n.getNodeType() == Node.ELEMENT_NODE) {
				if (n.getNodeName().equals("city")) {
					location.setCity(n.getTextContent());
				}
				if (n.getNodeName().equals("street")) {
					location.setStreet(n.getTextContent());
				}
				if (n.getNodeName().equals("zipCode")) {
					location.setZipCode(n.getTextContent());
				}
			}
		}
		return location;
	}

	private List<Item> parseItems(NodeList nodeList) {
		List<Item> items = new ArrayList<Item>();
		for (int i = 0; i < nodeList.getLength(); i++) {
			Node n = nodeList.item(i);
			if (n.getNodeType() == Node.ELEMENT_NODE) {
				Item item = new Item();
				for (int j = 0; j < n.getChildNodes().getLength(); j++) {
					Node child = n.getChildNodes().item(j);
					if (child.getNodeName().equals("category")) {
						item.setCategory(parseCategory(child.getChildNodes()));
				}
					if (child.getNodeName().equals("description")) {
						item.setDescription(child.getTextContent());
				}
					if (child.getNodeName().equals("name")) {
						item.setName(child.getTextContent());
				}
					if (child.getNodeName().equals("ratings")) {
						item.setRatings(parseRatings(child.getChildNodes()));
				}
				}
				items.add(item);
			}
		}
		return items;
	}

	private Category parseCategory(NodeList nodeList) {
		Category category = new Category();
		for (int i = 0; i < nodeList.getLength(); i++) {
			Node n = nodeList.item(i);
			if (n.getNodeType() == Node.ELEMENT_NODE) {
				if (n.getNodeName().equals("name")) {
					category.setName(n.getTextContent());
				}
				}

		}
		return category;
	}

	private List<Rating> parseRatings(NodeList nodeList) {
		List<Rating> list = new ArrayList<Rating>();
		for (int i = 0; i < nodeList.getLength(); i++) {
			Node n = nodeList.item(i);
			if (n.getNodeType() == Node.ELEMENT_NODE) {
				Rating rating = new Rating();
				for (int j = 0; j < n.getChildNodes().getLength(); j++) {
					Node child = n.getChildNodes().item(j);
					if (child.getNodeName().equals("name")) {
						rating.setName(child.getTextContent());
				}
				}
				list.add(rating);
			}
		}
		return list;
	}

}
